home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / STUTTGART / LANG / C / LIB / UNIXLIB37B / !UnixLib37 / src / signal / c / sigvec < prev    next >
Text File  |  1996-11-09  |  3KB  |  134 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /unixb/home/unixlib/source/unixlib37/src/signal/c/RCS/sigvec,v $
  4.  * $Date: 1996/10/30 22:04:51 $
  5.  * $Revision: 1.1 $
  6.  * $State: Rel $
  7.  * $Author: unixlib $
  8.  *
  9.  * $Log: sigvec,v $
  10.  * Revision 1.1  1996/10/30 22:04:51  unixlib
  11.  * Initial revision
  12.  *
  13.  ***************************************************************************/
  14.  
  15. static const char rcs_id[] = "$Id: sigvec,v 1.1 1996/10/30 22:04:51 unixlib Rel $";
  16.  
  17. /* c.sigvec: Written by Nick Burrett, 30 August 1996.  */
  18.  
  19. #include <signal.h>
  20. #include <errno.h>
  21. #include <stddef.h>
  22.  
  23.  
  24. /* We use a wrapper handler to support SV_RESETHAND.  */
  25.  
  26. static __sighandler_t wrapped_handlers[NSIG];
  27. static sigset_t wrapped_masks[NSIG];
  28.  
  29. static void wrapper_handle (int sig)
  30. {
  31.   int save;
  32.   struct sigaction act;
  33.  
  34.   act.sa_handler = SIG_DFL;
  35.   act.sa_mask = wrapped_masks[sig];
  36.   act.sa_flags = 0;
  37.   save = errno;
  38.   (void) sigaction(sig, &act, (struct sigaction *) NULL);
  39.   errno = save;
  40.  
  41.   (*wrapped_handlers[sig])(sig);
  42. }
  43.  
  44.  
  45. static int convert_mask (sigset_t *set, const int mask)
  46. {
  47.   register int sig;
  48.  
  49.   if (sigemptyset(set) < 0)
  50.     return -1;
  51.  
  52.   for (sig = 1; sig < NSIG; ++sig)
  53.     if (mask & sigmask(sig))
  54.       if (sigaddset(set, sig) < 0)
  55.     return -1;
  56.  
  57.   return 0;
  58. }
  59.  
  60. /* If VEC is non-NULL, set the handler for SIG to the `sv_handler' member
  61.    of VEC.  The signals in `sv_mask' will be blocked while the handler runs.
  62.    If the SV_RESETHAND bit is set in `sv_flags', the handler for SIG will be
  63.    reset to SIG_DFL before `sv_handler' is entered.  If OVEC is non-NULL,
  64.    it is filled in with the old information for SIG.  */
  65. int sigvec (int sig, const struct *vec, struct sigvec *ovec)
  66. {
  67.   struct sigaction old;
  68.  
  69.   if (vec == NULL || !(vec->sv_flags & SV_RESETHAND))
  70.     {
  71.       struct sigaction new, *n;
  72.  
  73.       if (vec == NULL)
  74.     n = NULL;
  75.       else
  76.     {
  77.       n = &new;
  78.       n->sa_handler = vec->sv_handler;
  79.       if (convert_mask (&n->sa_mask, vec->sv_mask) < 0)
  80.         return -1;
  81.       n->sa_flags = 0;
  82.  
  83.       if (vec->sv_flags & SV_ONSTACK)
  84.         {
  85.           n->sa_flags |= SA_ONSTACK;
  86.         }
  87.       if (!(vec->sv_flags & SV_INTERRUPT))
  88.         n->sa_flags |= SA_RESTART;
  89.     }
  90.  
  91.       if (sigaction (sig, n, &old) < 0)
  92.     return -1;
  93.     }
  94.   else
  95.     {
  96.       struct sigaction wrapper;
  97.  
  98.       wrapper.sa_handler = wrapper_handler;
  99.       wrapped_handlers[sig] = vec->sv_handler;
  100.       if (convert_mask (&wrapped_masks[sig], vec->sv_mask) < 0)
  101.     return -1;
  102.  
  103.       if (sigaction (sig, &wrapper, &old) < 0)
  104.     return -1;
  105.     }
  106.  
  107.   if (ovec != NULL)
  108.     {
  109.       register int i;
  110.       int mask = 0;
  111.  
  112.       for (i = 1; i < NSIG; ++i)
  113.     if (sigismember(&old.sa_mask, i))
  114.       mask |= sigmask(i);
  115.  
  116.       ovec->sv_mask = mask;
  117.       ovec->sv_flags = 0;
  118.  
  119.       if (old.sa_flags & SA_ONSTACK)
  120.     ovec->sv_flags |= SV_ONSTACK;
  121.       if (!(old.sa_flags & SA_RESTART))
  122.     ovec->sv_flags |= SV_INTERRUPT;
  123.       if (old.sa_handler == wrapper_handler)
  124.     {
  125.       ovec->sv_flags |= SV_RESETHAND;
  126.       ovec->sv_handler = wrapped_handlers[sig];
  127.     }
  128.       else
  129.     ovec->sv_handler = old.sa_handler;
  130.     }
  131.  
  132.   return 0;
  133. }
  134.